import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static int[][] schedule;
    public static void process(int k, int[][] schedule) {
//		计算运动员总人数
        int n = 1;
        for (int i = 0; i < k; i++) n*=2;
//		分配空间，零行零列空缺
        schedule = new int[n+1][n+1];
//		顺次列出运动员编号schedule[1][1]~schedule[1][n]
        for (int i = 1; i <= n; i++) schedule[1][i] = i;
        int m = 1;
        for (int s = 1; s <= k; s++) {
            n/=2;
            for (int t = 1; t <= n; t++) {
                for (int i = m + 1; i <= 2 * m; i++) {
                    for (int j = m + 1; j <= 2 * m; j++) {//
//						根据这个日程表对应规律可知，行和列都差了m
                        schedule[i][j+(t-1)*m*2]=schedule[i-m][j+(t-1)*m*2-m];
                        schedule[i][j+(t-1)*m*2-m]=schedule[i-m][j+(t-1)*m*2];
                    }
                }
            }
            m*=2;
        }
        for (int[] item : schedule)
            System.out.println(Arrays.toString(item));
        System.out.println();
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //输入k,运动员的人数为2^k
        int k;
        Scanner scanner = new Scanner(System.in);
        k = scanner.nextInt();
        process(k,schedule);

    }

}
